<?php


$base_dir = ".";
$menu_file = "$base_dir/qa.txt";
const MENU = "MENU:";
const SUB_MENU = "SUB-MENU:";
const COMMA = ",";
const COLON = ":";
const CURL_OPEN = "{";
const CURL_CLOSE = "}";
const AT = "@";
const HASH = "#";
const STAR = "*";
const SPL_FIELD_START = "((";
const SPL_FIELD_END = "))";
const HYPHEN = "-";
const DECIDE = "DECIDE:";
const R_ARROW = "->";
const CHOICE = "choice:";
const TITLE = "title";
const COMMENTS = "comments";
const C_DEFAULT = "default:";
const C_CORRECT = "correct:";
const C_THIS = "{this}";
const C_ALL = "{all}";
const C_NONE = "{none}";
const C_MAP = "map:";
const C_HEADER = "header";
const C_CONTENTS = "contents";
const C_DISPLAY = "display:";
const C_STOP = "STOP";


// Declarations
$gmap_relmap = array();
$gmap_vars = array();
$gmap_display_title = array();
$gmap_decide = array();
$gmap_decide_st = array();
$gmap_correct = array();
$gmap_default = array();
$gmap_default_submenu = array();
$gmap_correct_submenu = array();
$gmap_menu = array();
$gmap_submenu = array();
$gmap_submenu_st = array();
$gmap_map = array();
$gmap_comments = array();
$gmap_display_comments = array();
$gmap_topref = array();
$gmap_decide_display_title = array();
$gmap_decide_display_comments = array();
$pidx = 0;
$sidx = 0;
// starting pointers
$menu_arr_c = 0;
$menu_arr = array();

// ======================================= //
$choice_arr = array();
$default_arr = array();
$title_arr = array();
$comments_arr = array();
// ======================================= //

$final_sel = "";
$exp_final_sel = "";
$main_menu_selected  = "";
// ==================================================================== //
// MAIN MENU
// ==================================================================== //
if (check_file_exists($menu_file)) {

	// parse and collect the data
	parse_menu_file($menu_file);	
	
	

	// populate the rel map
	$gmc = 1;
	foreach ($gmap_menu as $gmi) {
		//print "checking: $gmi\n";
		$tmp1 = clean_fields($gmi);
		foreach($tmp1 as $k => $v) {
			$gmap_relmap["$v"] = $gmc;
		}
		$gmc++;
	}
	//print_r($gmap_relmap);
	
	// Create the top level menu
	$tmp1 = implode(COMMA, $gmap_menu);
	$gmap_topref = clean_fields($tmp1);
	$launch_arr = array_values($gmap_topref);	
	create_start_menu($launch_arr);
	$sel_menu = read_choice();
	$final_sel .= $sel_menu;
	$main_menu_selected = getSeq($sel_menu);
	
	//print "FINALIZE: $main_menu_selected, $sel_menu\n";
	$osr_sel = $gmap_topref[$sel_menu - 1];
	
	// Testing
	$pidx = $gmap_relmap[$osr_sel];
	
	decide_menu($osr_sel);
	
	// Create the sub menu
	create_sub_menu($gmap_submenu[$pidx]);
	
	print "\nYour final choise is: $final_sel\n";	
}
// ==================================================================== //


function expand_var($in) {
	global $gmap_vars;
	$chk1 = strpos($in, CURL_OPEN);
	if ($chk1 !== false) {
		//print "This variable needs to be expanded:: $in\n";
		list($nv, $v) = explode(CURL_OPEN, $in);
		$v = trim(str_replace(CURL_CLOSE, "", $v));
		//print "\n$v!\n";
		//print "\nfrom map ::::$gmap_vars[$v]\n";
		if (array_key_exists($v, $gmap_vars)) {
			$in = $gmap_vars[$v];
			//print "expanded: $in\n";
			expand_var($in);
		} 
	} 
	//print "expanded: $in\n";
	return $in;
}
function err_exit($mesg) {
	print "$mesg\n";
	exit;
}
function parse_menu_file ($menu_file) {
	global $gmap_vars , $gmap_relmap, $gmap_title, $gmap_submenu_st, $gmap_decide_st, $gmap_decide ,$gmap_correct ,$gmap_default ,$gmap_default_submenu ,$gmap_correct_submenu ,$gmap_menu ,$gmap_submenu ,$gmap_map ,$gmap_comments ,$gmap_display_title ,$gmap_decide_display_title;
	
	
	$fc = file($menu_file);
	
	
	$lc = 0;
	$menuc = 0;
	$submenuc = 0;
	$mseq = 0;
	$smseq = 0;

	$menu_flag = false;
	$submenu_flag = false;
	
	$buffer_menuc = 0;
	$buffer_submenuc = 0;
	
	while ($lc < count($fc)) {
		// keep iterating the file lines
		$osr_line = trim($fc[$lc]);
		if ($osr_line === "") {
			//print ".\n";
			$one = 0;
		} else {
			// start parsing
			
			if (startsWith($osr_line, C_MAP, false)) {
				$osr_line_details = get_details_of_def($osr_line, C_MAP);
				list($md, $lx1) = explode(R_ARROW, $osr_line_details);
				$md = trim($md);
				$lx1 = trim($lx1);
				$gmap_map[$md] = expand_all($lx1);
				//print "MAP: $osr_line_details\n";		
			}
			else if (startsWith($osr_line, MENU, false)) {
				$osr_line_details = get_details_of_def($osr_line, MENU);
				//print "MENU: $menuc $osr_line_details\n";	
				$submenuc = 0;
				$menu_flag = true;
				$submenu_flag = false;
				$mseq = getSeq($menuc);
				$gmap_menu[$mseq] = expand_all($osr_line_details); 
			}
			else if (startsWith($osr_line, SUB_MENU, false)) {
				$stc="";
				$chk=strpos($osr_line, C_STOP);
				if ($chk!== false) {
					list($osr_line, $st)= explode(C_STOP, $osr_line);
					$osr_line=trim($osr_line);
					$stc="yes";
				}
				$dchk = strpos($osr_line, AT);
				if ($dchk !== false) {
					list($sos, $d) = explode(AT, $osr_line);					
					$osr_line = str_replace($d, "", $osr_line);
					$osr_line = str_replace(AT, "", $osr_line);
					$ed = expand_var($d);
					store_display_details(SUB_MENU, $ed, $menuc, $submenuc);
				}
				$osr_line_details = get_details_of_def($osr_line, SUB_MENU);
				$lx = str_ireplace(SUB_MENU, "", $osr_line_details);
				$mseq = getSeq($menuc);
				$smseq = getSeq($submenuc);
				$gmap_submenu[$mseq][$smseq] = $lx;
				$submenu_flag = true;
				$menu_flag = false;
				$mseq = getSeq($menuc); 
				$smseq = getSeq($submenuc);
				$gmap_submenu[$mseq][$smseq] = expand_all($osr_line_details);
				if($stc=="yes") {
					$gmap_submenu_st[$mseq][$smseq]=C_STOP;
				}
				else {
					$gmap_submenu_st[$mseq][$smseq]="GO";
				}
				//print "SUB_MENU: $osr_line_details\n";
			}

			
			else if (startsWith($osr_line, DECIDE, false)) {
	
				$st=0;
				$chk=strpos($osr_line, C_STOP);
				if ($chk!== false) {
					list($d, $st)= explode(C_STOP, $osr_line);
					$osr_line=trim($d);
					$st=1;
					//print"$osr_line has stop";
				}
				
				$dchk = strpos($osr_line, AT);
				$osr_line_details = get_details_of_def($osr_line, DECIDE);
				list($md, $lx1) = explode(R_ARROW, $osr_line_details);
				$md = trim($md);
				$lx1 = trim($lx1);					
				if ($dchk !== false) {
					list($sos, $d) = explode(AT, $osr_line);					
					//$osr_line = str_replace($d, "", $osr_line);
					//$osr_line = str_replace(AT, "", $osr_line);					
					$ed = expand_var($d);
					//print "DKEY: $ed $md\n";
					store_decide_display_details( $ed, $md );
				}
				if ($st==1) {
					$gmap_decide_st[$md]=C_STOP;
				}
				$gmap_decide[$md] = $lx1;
			}
			else if (startsWith($osr_line, C_CORRECT, false)) {
				$osr_line_details = get_details_of_def($osr_line, C_CORRECT);	
				if ($menu_flag) {
					$gmap_correct[$menuc] = expand_all($osr_line_details);
				} 
				else {
					$gmap_correct[$menuc][$submenuc] = expand_all($osr_line_details);
				}
				//print "DEFAULT: $menuc $submenuc $menu_flag $osr_line_details\n";
			}	
			else if (startsWith($osr_line, C_DEFAULT, false)) {
				$osr_line_details = get_details_of_def($osr_line, C_DEFAULT);	
				if ($menu_flag) {
					$gmap_default[$menuc] = expand_all($osr_line_details);
				} 
				else {
					$gmap_default[$menuc][$submenuc] = expand_all($osr_line_details);
				}
				//print "DEFAULT: $menuc $submenuc $menu_flag $osr_line_details\n";
			}		
			// check comments
			else if (startsWith($osr_line, HASH, false)) {
				//print "Comment: $osr_line\n";
				$gmap_comments[$lc] = $osr_line;
			} else {
				if ( ($menu_flag !== true) && ($submenu_flag !== true)) {
					//print "Variable: $osr_line\n";
					list($var_name, $var_ref) = explode(COLON, $osr_line);
					$var_name = trim($var_name);
					$var_ref = trim($var_ref);
					$gmap_vars["$var_name"] = $var_ref;
				}
			}
				
			
		}
		
		// counters and flags for next iteration
		if ($menu_flag) {
			$menuc++;
			$menu_flag = false;
		} 
		if ($submenu_flag) {
			$submenu_flag = false;
			$submenuc++;
		}
		
		//print "$osr_line\n";
		$lc++;
		
	}
	/*
	
	print_r($gmap_comments);
	print_r($gmap_decide);*/
	print "======= menu ===============\n";
	//print_r($gmap_menu);
	//print_r($gmap_submenu);
	//print_r($gmap_decide);
	//print_r($gmap_display_title);
	//print_r($gmap_decide_st);
	//print_r($gmap_decide_display_title);
	//print_r($gmap_vars);
	//print_r($gmap_relmap);
	//print_r($gmap_correct);
	//print_r($gmap_map);
	//print_r($gmap_default);
	
	/*
	// 12112223432
	// Testing
	print_r($mb_menu);
	print_r($menu_ref);
	print_r($mb_var);
	print_r($top_ref);
	print_r($r_map);
	*/
	
	
	
	
}
function expand_all ($instr) {
	$evar = clean_fields($instr);
	$ret_str = "";
	$ret_tmp = array();
	foreach($evar as $evi) {
		array_push($ret_tmp, expand_var($evi));
	}
	$ret_str = implode(COMMA, $ret_tmp);
	return $ret_str;
}
function get_details_of_def ($line, $def) {
	// step1: get the menu, and take all the menu ptrs
	$line = str_ireplace($def, "", $line);
	$line = trim($line);
	return $line;
}
	
function clean_fields ($str) {
	$tarr = explode(",", $str);
	
	$rarr = array();
	foreach ($tarr as $titem) {
		array_push($rarr, trim($titem));
	}
	
	return $rarr;
}

function check_file_exists ($filename) {
	if (!file_exists($filename)) {
		//print "Error: $filename not found\n";
		exit;
	}
	return true;
}
function create_sub_menu($inArray) {
	global $gmap_display_title, $gmap_display_comments, $gmap_submenu_st, $final_sel, $exp_final_sel, $main_menu_selected, $f_map, $pidx, $sidx;
	$mc=1;	
	$cnt=0;
	//print_r($inArray);
	foreach ($inArray as $menu_item) {
		
		if ($menu_item !== "") {
			//print "===================\n";
			$menu_array = clean_fields($menu_item);
			$exp_menu = array();
			foreach ($menu_array as $mi) {
				$mx = expand_var($mi);
				$tmx = clean_fields($mx);
				$mx = join(COMMA, $tmx);
				$amx = explode(COMMA,$mx);
				$exp_menu = array_merge($exp_menu, $amx);			
			}
			
			if(array_key_exists ( $cnt , $gmap_display_title[$pidx] )){			
				$this_title = $gmap_display_title[$pidx][$cnt];				
				print "\n\n>> $this_title\n\n";
			}
			$cnt++;
			//print_r($exp_menu);
			print"\n";
			create_menu($exp_menu);
			$sel_menu = read_choice();
			$final_sel .= $sel_menu;			
			if ($gmap_submenu_st[$pidx][$cnt-1]===C_STOP) {
				exit;
			}
			// decide menu
			decide_menu($exp_menu[$sel_menu - 1]);
			
			$sm_selected = getSeq($mc);
			//print "TESTING: [$main_menu_selected][$sm_selected] ==> $sel_menu\n";
			$f_map[$main_menu_selected][$sm_selected] = $exp_menu[$sel_menu - 1];
			$f_map[$main_menu_selected][$sm_selected.".sel"] = $sel_menu - 1;
			$f_map[$main_menu_selected][$sm_selected.".ref"] = $exp_menu;
			$mc++;
			
		}
		
	}

}
function store_decide_display_details ($osr_line_details, $dkey) {
	global $gmap_display_title, $gmap_display_comments, $gmap_decide_display_title, $gmap_decide_display_comments;
	$arrTitlePtr = array();$arrCommentsPtr = array();

	
	$dtmp1 = clean_fields($osr_line_details);
	//$submenuc++;
	//print "$osr_line_details ===> $menuc, $submenuc\n"; exit;
	foreach ($dtmp1 as $d => $d1) {
		//print "CHECKING: $d, $d1\n";

		list($md, $lx1) = explode(R_ARROW, $d1);
		$md = trim($md);
		$lx1 = trim($lx1);
		$lx2 = expand_var($lx1);
		//print "$md, $lx2 $menuc, $submenuc\n";
		//sleep(1);

		if ($md === "title") {$gmap_decide_display_title[$dkey] = $lx2;}
		if ($md === "comments") {$gmap_decide_display_comments[$dkey] = $lx2;}
	}
	
	
	
}

function store_display_details ($cat, $osr_line_details, $menuc, $submenuc) {
	global $gmap_display_title, $gmap_display_comments, $gmap_decide_display_title, $gmap_decide_display_comments;
	$arrTitlePtr = array();$arrCommentsPtr = array();
	if ($cat === DECIDE) {$arrTitlePtr = $gmap_decide_display_title; $arrCommentsPtr = $gmap_decide_display_comments;}
	if ($cat === SUB_MENU) {$arrTitlePtr = $gmap_display_title; $arrCommentsPtr = $gmap_display_comments;}
	$dtmp1 = clean_fields($osr_line_details);
	//$submenuc++;
	//print "$osr_line_details ===> $menuc, $submenuc\n"; exit;
	foreach ($dtmp1 as $d => $d1) {
		//print "CHECKING: $d, $d1\n";

		list($md, $lx1) = explode(R_ARROW, $d1);
		$md = trim($md);
		$lx1 = trim($lx1);
		$lx2 = expand_var($lx1);
		//print "$md, $lx2 $menuc, $submenuc\n";
		//sleep(1);

		if ($md === "title") {$arrTitlePtr[$menuc][$submenuc] = $lx2;}
		if ($md === "comments") {$arrCommentsPtr[$menuc][$submenuc] = $lx2;}
	}
	if ($cat === DECIDE) {$gmap_decide_display_title = $arrTitlePtr; $gmap_decide_display_comments = $arrCommentsPtr;}
	if ($cat === SUB_MENU) {$gmap_display_title  = $arrTitlePtr; $gmap_display_comments  = $arrCommentsPtr;}
	
}
function create_start_menu($inArray) {
	global $menu_arr, $menu_arr_c;
	$menu_arr_c = 1;
	
	
	
	foreach ($inArray as $menu_item) {
		
		if ($menu_item !== "") {
			$chk1 = strpos($menu_item, CURL_OPEN);
			if ($chk1 !== false) {
				$mi = expand_var($menu_item);
				$mia = clean_fields($mi);
				$menu_arr_c++;
				create_start_menu($mia);
			} else {
				$menu_arr[$menu_arr_c - 1] = $menu_item;
				print "$menu_arr_c: $menu_item\n";
				$menu_arr_c++;
			}
		}
	}
	
}
function decide_menu($osr_sel) {	
	global $gmap_decide, $final_sel, $gmap_decide_display_title, $pidx, $gmap_decide_st;
	
	if (array_key_exists($osr_sel, $gmap_decide)) {
		$osr_d_menu = $gmap_decide[$osr_sel];
		
		$cnt=0;
		
		if(array_key_exists ( $osr_sel , $gmap_decide_display_title )){			
			$this_title = $gmap_decide_display_title[$osr_sel];				
			print "\n\n>> $this_title\n\n";
		}
		$cnt++;
		
		$dchk = strpos($osr_d_menu, AT);
		
		if ($dchk !== false) {
			list($sos, $d) = explode(AT, $osr_d_menu);
			$sos=trim($sos);		
			$osr_ar = expand_var($sos);
		}
		else {
			$osr_ar = expand_var($osr_d_menu);
		}
		$ed=explode(COMMA,$osr_ar);
		$osr_arr=array();
		$cnt=0;
		foreach ($ed as $val) {
			$osr_arr[$cnt]= trim($val);
			$cnt++;
		}
		create_menu($osr_arr);
		$d1_sel = read_choice();
		$final_sel .= "/".$d1_sel;                           ///////////////// "why /"
		if (array_key_exists($osr_sel, $gmap_decide_st)) {
			if($gmap_decide_st[$osr_sel]===C_STOP) {
				exit;
			}
		}
		if (array_key_exists($d1_sel - 1, $osr_arr)) {
			$d1_ref = $osr_arr[$d1_sel - 1];
			decide_menu($d1_ref);
		}
	}
}
function create_menu($inArray) {	
	$mc=1;
	//print "CHECKING::: ";
	//print_r($inArray);
	foreach ($inArray as $menu_item) {		
		if ($menu_item !== "") {
			print "$mc: $menu_item\n";
			$mc++;
		}
	}	
}
function read_choice() {
	print "\n\nPlease enter your choice no.: ";
	$choice1 = stream_get_line(STDIN, 1024, PHP_EOL);
	print "You selected => $choice1\n";
	return $choice1;
}

function startsWith($haystack,$needle,$case=true) {
    if($case){return (strcmp(substr($haystack, 0, strlen($needle)),$needle)===0);}
    return (strcasecmp(substr($haystack, 0, strlen($needle)),$needle)===0);
}

function endsWith($haystack,$needle,$case=true) {
    if($case){return (strcmp(substr($haystack, strlen($haystack) - strlen($needle)),$needle)===0);}
    return (strcasecmp(substr($haystack, strlen($haystack) - strlen($needle)),$needle)===0);
}

function getSeq($inPtr) {
	
	$seq = array('0','1','2','3','4','5','6','7','8','9','a','b','c','d','e','f','g','h','i','j','k','l','m','n','o','p','q','r','s','t','u','v','w','x','y','z',
	);

	return $seq[$inPtr];

}

function getSeqCS($inPtr) {
	
	$seq = array('0','1','2','3','4','5','6','7','8','9','a','b','c','d','e','f','g','h','i','j','k','l','m','n','o','p','q','r','s','t','u','v','w','x','y','z',
	'A','B','C','D','E','F','G','H','I','J','K','L','M','N','O','P','Q','R','S','T','U','V','W','X','Y','Z');

	return $seq[$inPtr];

}
/*
$d = str_replace(CURL_OPEN, "", $d);
					$d = str_replace(CURL_CLOSE, "", $d);
if (startsWith($osr_line, C_DISPLAY, false)) {
				$osr_line_details = get_details_of_def($osr_line, C_DISPLAY);
				//print "DISPLAY: $osr_line_details\n";
				$dtmp1 = clean_fields($osr_line_details);
				foreach ($dtmp1 as $d => $d1) {
					//print "CHECKING: $d, $d1\n";

					list($md, $lx1) = explode(R_ARROW, $d1);
					$md = trim($md);
					$lx1 = trim($lx1);
					$lx2 = expand_var($lx1);
				
					if ($menu_flag) {
						if ($md === "title") $gmap_title[$menuc] = $lx2;
						if ($md === "comments") $gmap_comments[$menuc] = $lx2;
					} 
					else {
						if ($md === "title") $gmap_title[$menuc][$submenuc] = $lx2;
						if ($md === "comments") $gmap_comments[$menuc][$submenuc] = $lx2;
					}
				}
			}

*/

?>